package yang_yi_fan;

/**
 * @Author if
 * @Date 2021-01-23 下午 02:03
 */
public class YANG_YI_FAN_TH_Q2<V> {
    /**
     * 链表实现队列
     * size表示最大长度,length表示当前长度
     * front是队头，靠近出口的一端，入队时不动，出队时往next下覆盖
     * rear是队尾，靠近屁股一段，入队时需要赋值，出队时不动
     */
    private final int size=100;
    private int length=0;
    //队头,靠近出口
    private Node<V> front;
    //队尾,远离出口
    private Node<V> rear;
    class Node<V>{
        V v;
        Node next;
        public Node(V v, Node next) {
            this.v = v;
            this.next = next;
        }
    }
    //构造器初始化队列
    public YANG_YI_FAN_TH_Q2() {
        this.front = this.rear=null;
    }
    //入列
    public void push(V v){
        //判断是否达到队列最大值
        if(length>=size){
            System.out.println("队满请将元素出队");
            return ;
        //判空，不允许为null
        }else if(v==null){
            throw new NullPointerException("传入元素为null");
        }
        Node newNode=new Node(v,null);
        //队列空时同时赋值
        if(length==0){
            front=rear=newNode;
        //将新元素赋值给rear和rear.next，所以此时的rear是新元素且rear.next是空，保持在队列最后一个
        }else{
            rear.next=newNode;
            rear=newNode;
        }
        length++;
    }
    //出列
    public V pop(){
        //判空报异常
        if(length==0){
            throw new NullPointerException("队列为空");
        }
        //储存好元素值，防止被覆盖后元素丢失
        V v=front.v;
        front=front.next;
        length--;
        return v;
    }
    //获取队列长度
    public int getLength(){
        return length;
    }

    public static void main(String[] args) {
        YANG_YI_FAN_TH_Q2 queue=new YANG_YI_FAN_TH_Q2();
        for(int i=0;i<5;i++){
            queue.push(i+1);
        }
        System.out.println("出列前 队列长度为 "+queue.getLength());
        for(int i=0;i<5;i++){
            System.out.println("第"+(i+1)+"个元素的值为 "+queue.pop());
        }
        System.out.println("出列后 队列长度为 "+queue.getLength());
        System.out.println("此时队列空继续出栈抛出异常");
        System.out.println(queue.pop());
    }
}
